package com.iwhalecloud.bss.kite.cucc.order.bo.flow;

import com.google.common.collect.ImmutableSet;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.OrderFlowConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.order.flow.FlowEngine;
import com.iwhalecloud.bss.kite.dataservice.cache.DcSystemParamCache;
import com.iwhalecloud.bss.kite.dataservice.entity.CustomerOrder;
import com.iwhalecloud.bss.kite.dataservice.entity.OrderItem;
import com.iwhalecloud.bss.kite.dataservice.entity.flow.Flow;
import com.iwhalecloud.bss.kite.dataservice.entity.flow.OfferFlowConfig;
import com.iwhalecloud.bss.kite.dataservice.entity.flow.TacheType;
import com.iwhalecloud.bss.kite.dataservice.entity.order.OrderItemChange;
import com.iwhalecloud.bss.kite.dataservice.enums.TableConfig;
import com.iwhalecloud.bss.kite.dataservice.mapper.flow.FlowMapper;
import com.iwhalecloud.bss.kite.dataservice.mapper.order.CustomerOrderMapper;
import com.iwhalecloud.bss.kite.dataservice.mapper.order.OrderItemMapper;
import com.iwhalecloud.bss.kite.order.client.context.OrderContext;
import com.iwhalecloud.bss.kite.order.client.dto.OrderContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderFlowRequest;
import com.ztesoft.bss.base.staticdata.CoreDataInteract;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.order.base.consts.IKeyValues;
import com.ztesoft.bss.order.base.consts.StaticDataCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author yu.baocheng<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2020/2/23 12:11 上午 <br>
 * @since ZSmart_BSS_COC_R3.1<br>
 * <Description>
 * 订单流程操作类BO逻辑层
 * <br>
 */
@Component
public class OrderFlowOperateBO {

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    CustomerOrderMapper customerOrderMapper;

    @Autowired
    FlowMapper flowMapper;

    @Autowired
    OrderFlowQueryBO orderFlowQueryBO;

    // 需要过去开通的变动对应的TableName；
    public static final Set<String> NEED_TOIOM_TABLES = ImmutableSet.of(
        TableConfig.OFFER_INST.name(),
        TableConfig.PROD_INST.name(),
        TableConfig.PROD_INST_FUNC.name(),
        TableConfig.PROD_INST_STATE.name(),
        TableConfig.PROD_INST_REL.name(),
        TableConfig.OFFER_RES_INST_REL_EXT.name()
    );

    /**
     * 创建多笔订单流程
     * @author yu.baocheng@iwhalecloud.com<br>
     * @taskId <br>
     * @CreateDate 2020/2/27 2:55 下午 <br>
     * @since ZSmart_BSS_COC_R3.1<br>
     * @return: boolean
     */
    public boolean createOrdrFlows(String custOrderId, String custId) {

        // 过滤有效订单；
        /*Example example = new Example(OrderItem.class);
        example.createCriteria().andEqualTo("custOrderId", custOrderId).andEqualTo("belongCustId", custId).andIsNull("flowId");
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        orderItems = this.filterValidOrderItems(orderItems);*/

        // 调整客户订单的流水；
        this.updateCustSoNumber(custOrderId, custId);

        /*for (OrderItem orderItem : orderItems) {
            createOrderFlow(orderItem);
        }*/

        return Boolean.TRUE;
    }


    private boolean createOrderFlow(OrderItem orderItem) {
        OrderFlowRequest flowRequest = this.createOrderFlowRequest(orderItem, OrderFlowConsts.FLOW_INST_TYPE_ORDITEM);
        this.updateModOrderItemSkipOpen(flowRequest);

        //根据skip_open的状态判断是否需要过开通。
        String skipOpen = flowRequest.getOrderItem().getSkipOpen();
        if (KiteStringUtils.equals(skipOpen, KeyConsts.IFTRUE_T)) {
            flowRequest.setFlowTypeId(OrderFlowConsts.FLOW_PASS_TO_IOM);
        }
        // FIXME 规则埋点：

        // 创建实例
        Flow flow = createFlow(flowRequest);
        
        if (Objects.nonNull(flow)) {
            Example example = new Example(OrderItem.class);
            example.createCriteria().andEqualTo("orderItemId", orderItem.getOrderItemId()).andEqualTo("belongCustId",
                flow.getCustId());
            OrderItemMapper orderItemMapper = SpringUtil.getBean(OrderItemMapper.class);
            OrderItem updOrderItem = new OrderItem();
            updOrderItem.setFlowId(flow.getFlowId());

            orderItemMapper.updateByExampleSelective(updOrderItem, example);
        }
        return Boolean.TRUE;
    }

    private Flow createFlow(OrderFlowRequest request) {

        Flow flow = orderFlowQueryBO.isExistsFlow(request);

        if (Objects.nonNull(flow)) {
            return flow;
        }

        TacheType tacheType = orderFlowQueryBO.getFirstTacheTypeByFlowTypeId(request.getFlowTypeId());

        // 流程实例不存在，创建；
        flow = FlowEngine.newFlow(request.getFlowTypeId(), tacheType.getTacheTypeId(), request.getCustId());
        String flowId = FlowEngine.generateFlowId();
        flow.setFlowId(flowId);
        flow.setStatusReasonMessage("创建流程实例");
        flow.setInstType(request.getInstType());
        flow.setInstId(request.getOrderItem().getOrderItemId());
        flow.setStaffId(request.getOrderItem().getCreateStaff());
        FlowEngine.createTache(flow);
        return flow;
    }

    /***
     * Description: <br>
     * 创建订单流程请求对象
     * @author yu.baocheng@iwhalecloud.com<br>
     * @taskId <br>
     * @CreateDate 2020/2/29 12:37 上午 <br>
     * @since ZSmart_BSS_COC_R3.1<br>
     * @param orderItem:
     * @return: com.iwhalecloud.bss.kite.order.client.dto.OrderFlowRequest
     */
    private OrderFlowRequest createOrderFlowRequest(OrderItem orderItem, String instType) {
        OfferFlowConfig offerFlowConfig = orderFlowQueryBO.getOfferFlowConfig(orderItem.getApplyObjSpec(), orderItem.getServiceOfferId());
        OrderFlowRequest request = new OrderFlowRequest();
        request.setCustId(orderItem.getBelongCustId());
        request.setOfferId(orderItem.getApplyObjSpec());
        request.setFlowTypeId(offerFlowConfig.getFlowTypeId());
        request.setInstType(instType);
        request.setOrderItem(orderItem);
        request.setServiceOfferId(orderItem.getServiceOfferId());
        return request;
    }



    /***
     * Description: <br>
     * 当订单类型为修正单时候，还要看变动是否需要过服开，不需要则直接更新SKIP_OPEN字段；
     * @author yu.baocheng@iwhalecloud.com<br>
     * @taskId <br>
     * @CreateDate 2020/2/29 1:34 上午 <br>
     * @since ZSmart_BSS_COC_R3.1<br>
     * @return: void
     */
    private void updateModOrderItemSkipOpen(OrderFlowRequest flowRequest) {
        OrderItem orderItem = flowRequest.getOrderItem();
        if (Objects.isNull(orderItem)) {
            return;
        }

        if (KiteStringUtils.equals(CoreDataInteract.EVT_C_0003_1100, orderItem.getOperType())) {
            boolean needToIom = false;
            String skipOpen = orderItem.getSkipOpen();
            for (String tableName : NEED_TOIOM_TABLES) {
                List<OrderItemChange> changeItems = OrderContainer.ofRequest(OrderContext.getOrderRequest()).listOrderItemChangesByOrderItemId(orderItem.getOrderItemId(), tableName);
                if (KiteListUtils.isNotEmpty(changeItems) && KiteStringUtils.equals(KeyConsts.IFTRUE_T, skipOpen)) {
                    orderItem.setSkipOpen(KeyConsts.IFTRUE_F);
                }
                needToIom = true;
            }

            if (!needToIom) {
                orderItem.setSkipOpen(KeyConsts.IFTRUE_T);
            }
        }
    }


    /***
     * 【合规性检测】排除功能产品、可选包、终端设备、主产品的订单;
     * @author yu.baocheng@iwhalecloud.com<br>
     * @taskId <br>
     * @CreateDate 2020/2/28 1:02 上午 <br>
     * @since ZSmart_BSS_COC_R3.1<br>
     * @param orderItems
     * @return: java.util.List<com.iwhalecloud.bss.kite.dataservice.entity.OrderItem>
     */
    private List<OrderItem> filterValidOrderItems(List<OrderItem> orderItems) {
        List<OrderItem> returnList = orderItems;
        if (IKeyValues.IFTRUE_T.equals(DcSystemParamCache.getDcParamVal(IKeyValues.ORD_SWITCH))
            && KiteListUtils.isNotEmpty(orderItems)) {
            returnList = orderItems.stream()
                .filter(t -> (!(KiteStringUtils.equals(IKeyValues.ORDER_ITEM_CD_13, t.getOrderItemCd()) && KiteStringUtils.equals(StaticDataCode.FUNC_ON_SALES_ITEMS, t.getOfferKind()))
                    || (KiteStringUtils.equals(IKeyValues.ORDER_ITEM_CD_05, t.getOrderItemCd()) && KiteStringUtils.equals(StaticDataCode.RES_ON_SALES_ITEMS, t.getOfferKind()))
                    || (KiteStringUtils.equals(IKeyValues.ORDER_ITEM_CD_13, t.getOrderItemCd()) && KiteStringUtils.equals(StaticDataCode.PROD_ON_SALES_ITEMS, t.getOfferKind()))
                    || KiteStringUtils.equals(IKeyValues.OFFER_KIND_2, t.getOfferKind())))
                .collect(Collectors.toList());

        }
        return returnList;
    }

    /**
     * 获取有效客户订单流水；
     * @author yu.baocheng@iwhalecloud.com<br>
     * @taskId <br>
     * @CreateDate 2020/2/28 1:23 上午 <br>
     * @since ZSmart_BSS_COC_R3.1<br>
     * @param custOrderId:
     * @param custId:
     * @return: java.lang.String
     */
    private void updateCustSoNumber(String custOrderId, String custId) {
        // 根据客户标识，判断客户是否存在过程单
        List<CustomerOrder> customerOrders = null;

        Example example = new Example(CustomerOrder.class);
        example.createCriteria().andNotEqualTo("custOrderId", custOrderId).andEqualTo("custId", custId);
        customerOrders = customerOrderMapper.selectByExample(example);

        String custSoNumber = "";
        Iterator<CustomerOrder> customerOrderItems = customerOrders.iterator();
        if (customerOrderItems.hasNext()) {
            // 存在客户订单。
            CustomerOrder customerOrder = customerOrderItems.next();
            custSoNumber = customerOrder.getCustSoNumber();
        }
        else {
            custSoNumber = custOrderId;
        }

        // 更新到库表；
        example.clear();
        example.createCriteria().andEqualTo("custOrderId", custOrderId).andEqualTo("custId", custId);
        CustomerOrder customerOrder = new CustomerOrder();
        customerOrder.setStatusDate(LocalDateTime.now());
        customerOrder.setStatusCd(CoreDataInteract.EVT_0002_301100);
        // 更新到库表中。
        if (KiteStringUtils.isNotEmpty(custSoNumber)) {
            customerOrder.setCustSoNumber(custSoNumber);
        }
        customerOrderMapper.updateByExampleSelective(customerOrder, example);
    }
}
